﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Drawing;
//using System.Drawing.Drawing2D;

//namespace LowLevelGraphics.Filter
//{
//    // Nested Types
//    public class Chaincode
//    {
//        // Fields
//        public int area;
//        public string cracks;
//        public int perimeter;
//        public Point start;

//        // Methods
//        public Chaincode()
//        {
//        }
//    }

//    /// <summary>
//    /// This implementation will only work with gray level pics
//    /// </summary>
//    public class ChainCodeFilter : BaseImageFilter
//    {
//        private int dx = 1;
//        private int dy = 1;

//        protected bool m_bCodeWith0Zells = true;
//        private List<Chaincode> all_chaincodes = new List<Chaincode>();
//        protected byte[,] c2 = null;
//        protected byte[,] c0 = null;
//        protected byte[,] c1v = null;
//        protected byte[,] c1h = null;
//        protected byte C0, C1V, C1H, C2;
//        protected byte m_nThreshold = 1;
//        protected Point start = Point.Empty;
//        private Pen pinkpen = new Pen(Color.FromArgb(255, 128, 128), 3);
//        private Pen redpen = new Pen(Color.Red, 5);
//        private bool NullCells;

//        private int x;
//        private int y;
//        int xSize = 0;
//        int ySize = 0;

//        /// <summary>
//        /// Initializes a new instance of the <see cref="ChainCode"/> class.
//        /// </summary>
//        public ChainCodeFilter()
//        {
//            this.redpen.EndCap = LineCap.ArrowAnchor;
//            this.pinkpen.EndCap = LineCap.ArrowAnchor;
//        }

//        /// <summary>
//        /// Initializes a new instance of the <see cref="ChainCode"/> class.
//        /// </summary>
//        /// <param name="_chainCode">The _chain code.</param>
//        internal ChainCodeFilter(ChainCodeFilter _chainCode)
//        {
//        }

//        /// <summary>
//        /// Execute this Filter
//        /// A Debug Statement is written if a concrete Filter is called
//        /// </summary>
//        /// <param name="_bitmap"></param>
//        /// <returns></returns>
//        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
//        {
//            ySize = _bitmap.Height;
//            xSize = _bitmap.Width;
//            c1v = new byte[ySize, xSize + 1];

//            this.all_chaincodes.Clear();

//            if (m_bCodeWith0Zells)
//            {
//                this.NullCells = m_bCodeWith0Zells;
//            }
//            this.Chaincode_Finder(_bitmap);

//            return _bitmap;
//        }

//        /// <summary>
//        /// Start_crack_searches the specified _bitmap.
//        /// </summary>
//        /// <param name="_bitmap">The _bitmap.</param>
//        /// <returns></returns>
//        private bool Start_Crack_Search(UnsafeBitmap _bitmap)
//        {
//            this.y = this.start.Y;
//            while (this.y < 12)
//            {
//                this.x = 0;
//                while (this.x < 11)
//                {
//                    byte num;
//                    if (this.x > 0)
//                    {
//                        num = _bitmap[this.x - 1, this.y, true].R;
//                    }
//                    else
//                    {
//                        num = 0;
//                    }
//                    if (((num < this.m_nThreshold) && (_bitmap[this.x, this.y, true].R >= this.m_nThreshold)) && (this.c1v[this.y, this.x] == 0))
//                    {
//                        this.start.X = this.x;
//                        this.start.Y = this.y;
//                        this.c1v[this.y, this.x] = 1;
//                        return true;
//                    }
//                    this.x++;
//                }
//                this.y++;
//            }
//            return false;
//        }

//        /// <summary>
//        /// Chaincode_finders the specified _bitmap.
//        /// </summary>
//        /// <param name="_bitmap">The _bitmap.</param>
//        protected void Chaincode_Finder(UnsafeBitmap _bitmap)
//        {
//            sbyte[,] numArray = new sbyte[,] { { 0, -1 }, { 0, 0 }, { -1, 0 }, { -1, -1 } };
//            sbyte[,] numArray2 = new sbyte[,] { { 0, 0 }, { -1, 0 }, { -1, -1 }, { 0, -1 } };
//            Point point = new Point();
//            Point point2 = new Point();
//            this.y = 0;
//            while (this.y < 12)
//            {
//                this.x = 0;
//                while (this.x <= 11)
//                {
//                    this.c1v[this.y, this.x] = 0;
//                    this.x++;
//                }
//                this.y++;
//            }
//            this.start.X = this.start.Y = 0;
//            for (byte i = 1; this.Start_Crack_Search(_bitmap); i = (byte)(i + 1))
//            {
//                Chaincode chaincode = new Chaincode();
//                StringBuilder builder = new StringBuilder();
//                builder.Append('s');
//                chaincode.area = 0;
//                this.x = this.start.X;
//                this.y = this.start.Y + 1;
//                int num = 1;
//                Graphics graphics = null;//base.CreateGraphics();
//                do
//                {
//                    bool flag;
//                    bool flag2;
//                    _bitmap.UnlockImage();
//                    graphics = Graphics.FromImage(_bitmap.InternalBitmap);
//                    graphics.DrawLine(this.pinkpen, (int)(this.x * this.dx), (int)(this.y * this.dy), (int)((this.x * this.dx) + (this.dx / 4)), (int)(this.y * this.dy));
//                    graphics.DrawLine(this.pinkpen, (int)(this.x * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)((this.y * this.dy) + (this.dy / 4)));
//                    graphics.DrawLine(this.pinkpen, (int)(this.x * this.dx), (int)(this.y * this.dy), (int)((this.x * this.dx) - (this.dx / 4)), (int)(this.y * this.dy));
//                    graphics.DrawLine(this.pinkpen, (int)(this.x * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)((this.y * this.dy) - (this.dy / 4)));
//                    switch (builder[builder.Length - 1])
//                    {
//                        case 's':
//                            graphics.DrawLine(this.redpen, (int)(this.x * this.dx), (int)((this.y - 1) * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                            break;

//                        case 'w':
//                            graphics.DrawLine(this.redpen, (int)((this.x + 1) * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                            break;

//                        case 'e':
//                            graphics.DrawLine(this.redpen, (int)((this.x - 1) * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                            break;

//                        case 'n':
//                            graphics.DrawLine(this.redpen, (int)(this.x * this.dx), (int)((this.y + 1) * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                            break;
//                    }
//                    _bitmap.LockImage();
//                    long num3 = DateTime.Now.Ticks + 0x1e8480L;
//                    while (num3 > DateTime.Now.Ticks)
//                    {
//                    }
//                    point.X = this.x + numArray[num, 0];
//                    point.Y = this.y + numArray[num, 1];
//                    point2.X = this.x + numArray2[num, 0];
//                    point2.Y = this.y + numArray2[num, 1];
//                    try
//                    {
//                        flag = _bitmap[point.X, point.Y, true].R >= this.m_nThreshold;
//                    }
//                    catch
//                    {
//                        flag = false;
//                    }
//                    try
//                    {
//                        flag2 = _bitmap[point2.X, point2.Y, true].R >= this.m_nThreshold;
//                    }
//                    catch
//                    {
//                        flag2 = false;
//                    }
//                    if (flag2 && (flag || this.NullCells))
//                    {
//                        num = (num + 1) % 4;
//                    }
//                    else if (!flag && (!flag2 || !this.NullCells))
//                    {
//                        num = (num + 3) % 4;
//                    }
//                    switch (num)
//                    {
//                        case 0:
//                            builder.Append('e');
//                            this.x++;
//                            chaincode.area += this.y;
//                            break;

//                        case 1:
//                            builder.Append('s');
//                            this.y++;
//                            this.c1v[this.y - 1, this.x] = i;
//                            break;

//                        case 2:
//                            builder.Append('w');
//                            this.x--;
//                            chaincode.area -= this.y;
//                            break;

//                        case 3:
//                            builder.Append('n');
//                            this.y--;
//                            this.c1v[this.y, this.x] = i;
//                            break;
//                    }
//                }
//                while ((this.x != this.start.X) || (this.y != this.start.Y));
//                switch (builder[builder.Length - 1])
//                {
//                    case 'e':
//                        graphics.DrawLine(this.redpen, (int)((this.x - 1) * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                        break;

//                    case 'w':
//                        graphics.DrawLine(this.redpen, (int)((this.x + 1) * this.dx), (int)(this.y * this.dy), (int)(this.x * this.dx), (int)(this.y * this.dy));
//                        break;
//                }
//                chaincode.cracks = builder.ToString();
//                chaincode.perimeter = chaincode.cracks.Length;
//                this.all_chaincodes.Add(chaincode);
//            }
//        }

//        /// <summary>
//        /// This is used to clone a filter, each filter must implement it's own clone functionality
//        /// </summary>
//        /// <returns></returns>
//        public override object Clone()
//        {
//            return new ChainCodeFilter(this);
//        }
//    }
//}
